/* Copyright (c) 2022 渝州大数据实验室
 *
 * Lanius is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *
 *     http://license.coscl.org.cn/MulanPSL2
 *
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.yzbdl.lanius.orchestrate.interceptor;

import org.yzbdl.lanius.orchestrate.config.WhiteLists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
import org.yzbdl.lanius.orchestrate.serv.entity.system.PermissionEntity;
import org.yzbdl.lanius.orchestrate.serv.service.system.PermissionService;
import org.yzbdl.lanius.orchestrate.serv.utils.CurrentUserUtil;
import org.yzbdl.lanius.orchestrate.common.annotation.auth.CheckPermission;
import org.yzbdl.lanius.orchestrate.common.utils.ResponseUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

/**
 * 权限拦截器
 *
 * @author chenjunhao@yzbdl.ac.cn
 * @date 2022-04-12 09:26
 */
@Component
public class AuthInterceptor implements HandlerInterceptor {

	@Autowired
	PermissionService permissionService;

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
		/*
		 * 过滤掉资源类访问
		 */
		if(handler instanceof ResourceHttpRequestHandler){
			return true;
		}
		/*
			过滤掉管理员用户或组织领袖
		 */
		if(CurrentUserUtil.isManager()|CurrentUserUtil.isOrgChief()){
			return true;
		}
		/*
			过滤掉权限白名单
		 */
		if(inIgnoreUrl(request.getRequestURI())){
			return true;
		}

		if(handler instanceof HandlerMethod){
			Method method = ((HandlerMethod) handler).getMethod();
			if(method.isAnnotationPresent(CheckPermission.class)){
				CheckPermission checkPermission = method.getAnnotation(CheckPermission.class);
				List<PermissionEntity> ownerPermissions = permissionService.queryPermissionsByUserId(CurrentUserUtil.getCurrentUserId());
				String permissionCode = checkPermission.value();
				boolean hasPermission = ownerPermissions.stream().anyMatch(m -> m.getPermissionCode().equalsIgnoreCase(permissionCode));
				if(!hasPermission){
					ResponseUtil.noPermissionResponse(response);
					return false;
				}
				return true;
			}
			ResponseUtil.noPermissionResponse(response);
			return false;
		}
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) { }

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex){}

	/**
	 * 权限忽略url
	 * @param requestUrl 请求url
	 * @return 布尔值
	 */
    private boolean inIgnoreUrl(String requestUrl) {
        AntPathMatcher antPathMatcher = new AntPathMatcher();
        return Arrays.stream(WhiteLists.IGNORE_URLS).anyMatch(ignoreUrl->antPathMatcher.match(ignoreUrl, requestUrl));
    }

}
